package com.huhuamin.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huhuamin.mapper.LeafAllocMapper;
import com.huhuamin.model.LeafAlloc;
import com.huhuamin.model.Segment;
import com.huhuamin.model.SegmentBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;


import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * Created on 2021/10/20.
 *
 * @author huahuamin 175759041@qq.com
 * Description:
 */
public class LeafAllocServiceImpl extends ServiceImpl<LeafAllocMapper, LeafAlloc> implements ILeafAllocService {
    private static final Logger logger = LoggerFactory.getLogger(LeafAllocServiceImpl.class);
    private Map<String, SegmentBuffer> cache = new ConcurrentHashMap<>();

    @Override
    public void updateCacheFromDb() {
        logger.info("update cache from db");
        Long start = System.currentTimeMillis();
        try {
            List<String> dbTags = getAllTags();
            if (dbTags == null || dbTags.isEmpty()) {
                return;
            }
            //逻辑是
            //1. cache 在数据库不存在的时候cache key删除
            //例如 数据库[abcde] cache[abf]  那么f 需要删除
            List<String> cacheNotInDb = cache.keySet().stream().filter(t -> dbTags.contains(t)).collect(Collectors.toList());
            cacheNotInDb.stream().forEach((t) -> cache.remove(t));


            //2. 数据库存在的key cache key 没有的新增并初始化
            //例如 数据库[abcde] cache[abf]  cde 需要初始化buffer 切放到cache 里面

            dbTags.stream().forEach((key) -> {
                if (!cache.containsKey(key)) {
                    SegmentBuffer segmentBuffer = SegmentBuffer.initBuilder(key, cache);
                    logger.info("Add tag {} from db to IdCache, SegmentBuffer {}", key, segmentBuffer);
                    cache.put(key, segmentBuffer);
                }
            });


            //原始算法
//            List<String> cacheTags = new ArrayList<String>(cache.keySet());
//            Set<String> insertTagsSet = new HashSet<>(dbTags);
//            Set<String> removeTagsSet = new HashSet<>(cacheTags);
//            //db中新加的tags灌进cache
//            for (int i = 0; i < cacheTags.size(); i++) {
//                String tmp = cacheTags.get(i);
//                if (insertTagsSet.contains(tmp)) {
//                    insertTagsSet.remove(tmp);
//                }
//            }
//            for (String tag : insertTagsSet) {
//                SegmentBuffer buffer = new SegmentBuffer();
//                buffer.setKey(tag);
//                Segment segment = buffer.getCurrent();
//                segment.setValue(new AtomicLong(0));
//                segment.setMax(0);
//                segment.setStep(0);
//                cache.put(tag, buffer);
//                logger.info("Add tag {} from db to IdCache, SegmentBuffer {}", tag, buffer);
//            }
//            //cache中已失效的tags从cache删除
//            for (int i = 0; i < dbTags.size(); i++) {
//                String tmp = dbTags.get(i);
//                if (removeTagsSet.contains(tmp)) {
//                    removeTagsSet.remove(tmp);
//                }
//            }
//            for (String tag : removeTagsSet) {
//                cache.remove(tag);
//                logger.info("Remove tag {} from IdCache", tag);
//            }
        } catch (Exception e) {
            logger.warn("update cache from db exception", e);
        } finally {
            Long end = System.currentTimeMillis();
            logger.info("cost time " + (end - start));
        }

    }

    private List<String> getAllTags() {
        List<LeafAlloc> list = list();
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<String> collect = list.stream().map(LeafAlloc::getKey).collect(Collectors.toList());
        return collect;
    }
}
